"use strict";
/**
 * 变量声明
 */
// 使用 var 声明的变量可以在包含它的函数、模块、命名空间或全局作用域内部任何位置被访问，包含它的代码块对此没有什么影响
// 有些人称此为 var 作用域 或 函数作用域，函数参数也使用函数作用域
// 这些作用域规则可能会引发一些错误，多次声明同一个变量并不会报错
function sumMatrix(matrix) {
    var sum = 0;
    for (var i = 0; i < matrix.length; i++) {
        var currentRow = matrix[i];
        for (var i = 0; i < currentRow.length; i++) { // i 会被覆盖
            sum += currentRow[i];
        }
    }
    return sum;
}
// 捕获变量的怪异之处
for (var i = 0; i < 10; i++) {
    setTimeout(function () { console.log(i); }, 100 * i);
}
// 执行结果会返回 10 10 10 10 10 10 10 10 10 10
// 需要以下改造
// 一个通常的解决方法是使用立即执行的函数表达式（IIFE）来捕获每次迭代时i的值
for (var i = 0; i < 10; i++) {
    // capture the current state of 'i'
    // by invoking a function with its current value
    (function (i) {
        setTimeout(function () { console.log(i); }, 100 * i);
    })(i);
}
// 0 1 2 3 4 5 6 7 8 9
// 使用 let 关键字定义变量可以解决 var 存在的作用域问题
var str = 'Hello';
// 当使用 let 声明一个变量，它使用的是 词法作用域 或者 块作用域
// 块作用域在包含他们的块或者for循环之外是不能访问的
function f(input) {
    var a = 100;
    if (input) {
        // Still okay to reference 'a'
        var b_1 = a + 1;
        return b_1;
    }
    // Error: 'b' doesn't exist here
    // b 没有定义
    // return b;
}
// 在 cache 语句中声明的变量同样也有作用域规则
try {
    throw "oh No";
}
catch (e) {
    console.log(e);
}
// console.log(e) 错误 e 不可访问
// 拥有块级作用域的另一个特点是：他们不能在声明之前进行读和写
// 在同一作用域中，不能重复定义变量
// 解构
// 函数参数
function add(_a) {
    var num1 = _a[0], num2 = _a[1];
    return num1 + num2;
}
// 对象解构
var o = {
    a: "foo",
    b: 12,
    c: "bar"
};
var a = o.a, b = o.b;
function f1(_a) {
    var a = _a.a, b = _a.b;
    // ...
}
